package core;

import graphic.LogPanel;
import graphic.UsersPanel;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

public class ConnectionListener extends Thread {

	protected static ConnectionListener CONNECTIONLISTENER;
	
	ServerSocket serverSocket;
	
	HashMap<Socket, ConnectedClientThread> connections;
	
	public ConnectionListener() {	
		try {
			int port = Integer.parseInt(Server.getInstance().configs.get(3));
			this.serverSocket = new ServerSocket(port);
			
			this.connections = new HashMap<Socket, ConnectedClientThread>();
						
			this.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {

		Socket connection;
		while(!this.serverSocket.isClosed())
		{
			try {
				connection = this.serverSocket.accept();
				this.connections.put(connection, new ConnectedClientThread(connection));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
			}
		}
	}

	public synchronized void login(String userId, Socket connection, ObjectInputStream in, ObjectOutputStream out)
	{
		this.connections.remove(connection);
		Server.getInstance().getUsers().put(userId, new LoggedUserThread(userId, connection, in, out));
		UsersPanel.getInstance().addUser(userId, connection.getInetAddress());
		LogPanel.getInstance().writeLogMessage(userId, ServerParameters.USER_LOGGED_IN, "");
	}
	
	public synchronized void logout(String userId)
	{
		Server.getInstance().getUsers().remove(userId);
		UsersPanel.getInstance().removeUser(userId);
		LogPanel.getInstance().writeLogMessage(userId, ServerParameters.USER_LOGGED_OUT, "");
	}
	
	public void close() throws IOException
	{		
		for (Iterator iterator = this.connections.values().iterator(); iterator.hasNext();)
		{
			ConnectedClientThread client = (ConnectedClientThread) iterator.next();
			client.close();
		}
	
		for (Iterator iterator = Server.getInstance().getUsers().values().iterator(); iterator.hasNext();)
		{
			LoggedUserThread loggedUserThread = (LoggedUserThread) iterator.next();
			loggedUserThread.close();
		}
		
		this.serverSocket.close();
	}
	
	public static ConnectionListener getInstance()
	{
		if(CONNECTIONLISTENER == null) CONNECTIONLISTENER = new ConnectionListener();
		return CONNECTIONLISTENER;
	}	
}